package ru.braim.weather_app.services;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import ru.braim.weather_app.dto.region.RegionRequestDTO;
import ru.braim.weather_app.dto.region.RegionResponseDTO;
import ru.braim.weather_app.models.Account;
import ru.braim.weather_app.models.Region;
import ru.braim.weather_app.repositories.AccountRepository;
import ru.braim.weather_app.repositories.RegionRepository;
import ru.braim.weather_app.responses.region.RegionResponse;
import ru.braim.weather_app.utils.validators.models.RegionValidator;

import java.util.List;

@Service
public class RegionService {

    private final RegionRepository regionRepository;
    private final AccountRepository accountRepository;

    public RegionService(RegionRepository regionRepository, AccountRepository accountRepository) {
        this.regionRepository = regionRepository;
        this.accountRepository = accountRepository;
    }

    public RegionResponse createRegion(RegionRequestDTO regionRequestDTO, String cookie) {

        Region region = RegionValidator.getValidRegion(regionRequestDTO);
        Account account = accountRepository.getAccountByCookie(cookie);

        if (region == null) {
            return new RegionResponse(null, HttpStatus.BAD_REQUEST);
        }

        if (regionRepository.getRegionByLatitude1AndLongitude1(region.getLatitude1(), region.getLongitude1()) != null) {
            return new RegionResponse(null, HttpStatus.CONFLICT);
        }

        if (regionRepository.getRegionByLatitude2AndLongitude2(region.getLatitude2(), region.getLongitude2()) != null) {
            return new RegionResponse(null, HttpStatus.CONFLICT);
        }


        region.setAccount(account);
        region.setParentRegion(regionRequestDTO.getParentRegion());

        regionRepository.save(region);

        RegionResponseDTO regionResponseDTO = new RegionResponseDTO();

        regionResponseDTO.setId(region.getId());

        regionResponseDTO.setParentRegion(regionRequestDTO.getParentRegion());
        regionResponseDTO.setName(regionRequestDTO.getName());
        regionResponseDTO.setLatitude_1(regionRequestDTO.getLatitude_1());
        regionResponseDTO.setLongitude_1(regionRequestDTO.getLongitude_1());

        regionResponseDTO.setLatitude_2(regionRequestDTO.getLatitude_2());
        regionResponseDTO.setLongitude_2(regionRequestDTO.getLongitude_2());


        return new RegionResponse(regionResponseDTO, HttpStatus.CREATED);
    }


    public RegionResponse getRegionById(Long id) {

        if (id <= 0) {
            return new RegionResponse(null, HttpStatus.BAD_REQUEST);
        }

        Region region = regionRepository.findById(id).orElse(null);

        if (region == null) {
            return new RegionResponse(null, HttpStatus.NOT_FOUND);
        }



        RegionResponseDTO regionResponseDTO = new RegionResponseDTO();

        regionResponseDTO.setId(region.getId());
        regionResponseDTO.setAccountId((long) region.getAccount().getId());
        regionResponseDTO.setName(region.getName());
        regionResponseDTO.setParentRegion(region.getParentRegion());

        regionResponseDTO.setLatitude_1(region.getLatitude1());
        regionResponseDTO.setLongitude_1(region.getLongitude1());

        regionResponseDTO.setLatitude_2(region.getLatitude2());
        regionResponseDTO.setLongitude_2(region.getLongitude2());

        return new RegionResponse(regionResponseDTO, HttpStatus.OK);

    }

    public RegionResponse updateRegionById(Long id, RegionRequestDTO regionRequestDTO) {

        Region region = RegionValidator.getValidRegion(regionRequestDTO) ;

        if (region == null) {
            return new RegionResponse(null, HttpStatus.BAD_REQUEST);
        }

        Region regionFromRepository = regionRepository.findById(id).orElse(null);

        if (regionFromRepository == null) {
            return new RegionResponse(null, HttpStatus.NOT_FOUND);
        }

        regionFromRepository.setName(regionRequestDTO.getName());

        if (regionRequestDTO.getParentRegion() != null) {
            regionFromRepository.setParentRegion(regionRequestDTO.getParentRegion());
        }

        regionFromRepository.setLatitude_1(regionRequestDTO.getLatitude_1());
        regionFromRepository.setLongitude_1(regionRequestDTO.getLongitude_1());

        regionFromRepository.setLatitude_2(regionRequestDTO.getLatitude_2());
        regionFromRepository.setLongitude_2(regionRequestDTO.getLongitude_2());

        if (regionRepository.getRegionByLatitude1AndLongitude1
                (regionFromRepository.getLatitude1(), regionFromRepository.getLongitude1()) != null) {
            return new RegionResponse(null, HttpStatus.CONFLICT);
        }

        if (regionRepository.getRegionByLatitude2AndLongitude2
                (regionFromRepository.getLatitude2(), regionFromRepository.getLongitude2()) != null) {
            return new RegionResponse(null, HttpStatus.CONFLICT);
        }

        regionRepository.save(regionFromRepository);

        RegionResponseDTO regionResponseDTO = new RegionResponseDTO();

        regionResponseDTO.setId(regionFromRepository.getId());
        regionResponseDTO.setName(regionFromRepository.getName());
        regionResponseDTO.setParentRegion(regionFromRepository.getParentRegion());
        regionResponseDTO.setLatitude_1(regionFromRepository.getLatitude1());
        regionResponseDTO.setLongitude_1(regionFromRepository.getLongitude1());

        regionResponseDTO.setLatitude_2(regionFromRepository.getLatitude2());
        regionResponseDTO.setLongitude_2(regionFromRepository.getLongitude2());

        return new RegionResponse(regionResponseDTO, HttpStatus.OK);


    }

    public RegionResponse deleteRegionById(Long id) {

        if (id <= 0) {
            return new RegionResponse(null, HttpStatus.BAD_REQUEST);
        }

        Region region = regionRepository.findById(id).orElse(null);

        if (region == null) {
            return new RegionResponse(null, HttpStatus.NOT_FOUND);
        }

        List<Region> regionList = regionRepository.getRegionsByParentRegion(region.getName());

        if (!regionList.isEmpty()) {
            return new RegionResponse(null, HttpStatus.BAD_REQUEST);
        }

        regionRepository.delete(region);

        return new RegionResponse(null, HttpStatus.OK);

    }


}
